<?php

namespace addons\zzyy\controller\api;


use addons\zzyy\library\SaasCenter;
use addons\zzyy\library\Tongtongsuo;
use addons\zzyy\library\Yunding;
use addons\zzyy\library\Ykxbon;
use addons\zzyy\module\Weixin;
use app\admin\model\zzyy\ZzyyReserve;
use app\admin\model\zzyy\ZzyyRoom;
use app\admin\model\zzyy\ZzyySetting;
use app\admin\model\zzyy\ZzyyTransaction;
use app\admin\model\zzyy\ZzyyUserBalance;
use app\admin\model\zzyy\ZzyyUserExtend;
use fast\Http;
use think\Db;

class Reserve extends \app\common\controller\Api
{
    protected $noNeedLogin = ['*'];

    protected $_ispInfo = null;

    public function _initialize()
    {
        parent::_initialize(); // TODO: Change the autogenerated stub
        $this->_ispInfo = SaasCenter::getOpenPlatformMerchantIsp();
    }

    //
    public function order()
    {
        $post = $this->request->post();
        $user = $this->auth->getUser();
        if (null == $user) {
            $this->error('未登录', '', 401);
        }
        $userId = $user->id;

        $roomId = $post['room_id'];
        $startTime = Ykxbon::parse($post['start_time']);
        $endTime = Ykxbon::parse($post['end_time']);
        $price = $post['price'];

        $roomReserves = ZzyyReserve::where('room_id', $roomId)
            ->whereIn('status', [ZzyyReserve::STATUS_CREATED, ZzyyReserve::STATUS_SUCCESS])
            ->where('starttime', '>', $startTime->startOfDay()->toDateTimeString())
            ->where('starttime', '<' , $startTime->endOfDay()->toDateTimeString())
            ->select();

        foreach ($roomReserves as $v) {
            if ($startTime->betweenIncluded($v->starttime, $v->endtime)
                or $endTime->betweenIncluded($v->starttime, $v->endtime)) {
                $this->error('对不起，下单过程中此时间段全部或部分被别人抢占，请返回重新选择');
            }
        }

        $roomInfo = ZzyyRoom::get($roomId, 'store');
        $roomName = $roomInfo->room_name;
        $storeName = $roomInfo->store->store_name;

        $reserve = ZzyyReserve::create([
            'trade_no' => (function () {
                list($usec, $sec) = explode(" ", microtime());
                $usec = substr(str_replace('0.', '', $usec), 0 ,4);
                $str  = rand(10,99);
                return date("YmdHis").$usec.$str;
            })(),
            'user_id' => $userId,
            'store_id' => $roomInfo->store->id,
            'room_id' => $roomId,
            'starttime' => $startTime->toDateTimeString(),
            'endtime' => $endTime->toDateTimeString(),
            'fee' => $price,
            'status' => ZzyyReserve::STATUS_CREATED,
            'createtime' => time(),
            'updatetime' => time()
        ]);

        $this->success('ok', [
            'reserve_id' => $reserve->id,
            'store_name' => $storeName,
            'room_name' => $roomName,
            'starttime' => $startTime->toDateTimeString(),
            'endtime' => $endTime->toDateTimeString(),
            'price' => $price,
            'createtime' => $reserve->createtime
        ]);
    }

    public function updateOrderPaid()
    {
        $user = $this->auth->getUser();
        if (null == $user) {
            $this->error('未登录', '', 401);
        }

        $reserveId = $this->request->post('reserve_id');
        $payWay = $this->request->post('pay_way');
        $itemId = $this->request->post('item_id'); //支付方式的主键ID

        $reserve = ZzyyReserve::get($reserveId);

        $roomInfo = ZzyyRoom::get($reserve->room_id);

        if (ZzyyReserve::PAY_WAY_BALANCE == $payWay) {
            $reserve->pay_way = ZzyyReserve::PAY_WAY_BALANCE;
            $reserve->balance_id = $itemId;
        } else if (ZzyyReserve::PAY_WAY_DIRECT == $payWay) {
            $reserve->pay_way = ZzyyReserve::PAY_WAY_DIRECT;
            $reserve->transaction_id = $itemId;
        } else if (ZzyyReserve::PAY_WAY_OTHER == $payWay) {   // 其他，如0元支付
            $reserve->pay_way = ZzyyReserve::PAY_WAY_OTHER;
        }
        $reserve->status = ZzyyReserve::STATUS_SUCCESS;

        $msg = '预约成功';

        $config = get_addon_config('zzyy');

        //生成开门的密码
        if (empty($config['tongtongsuo_domain'])
            || empty($config['tongtongsuo_client_id'])
            || empty($config['tongtongsuo_client_secret'])
            || empty($config['tongtongsuo_username'])
            || empty($config['tongtongsuo_password'])
            || empty($roomInfo->tts_lockid)) {

        } else {

            $startTime = Ykxbon::parse($reserve->starttime);
            $endTime = Ykxbon::parse($reserve->endtime);

            $tts = new Tongtongsuo();
            $res = $tts->addPassword($roomInfo->tts_lockid, $user, $startTime->toDateTimeString(), $endTime->toDateTimeString());

            // 生成开门密码成功就保存，不成功不保存，
            if ($res) {
                $reserve->tts_bluekeyid = $res['blue_key_id'];
                $reserve->tts_bluelockdata = $res['blue_lock_data'];
                $reserve->tts_randkeyid = $res['rand_key_id'];
                $reserve->tts_randkeypwd = $res['rand_key_pwd'];

                $msg = '预约成功, 开门密码成功生成';
            } else {
                $msg = '预约成功, 但开门密码暂未生成，请联系管理员';
            }

        }

        $reserve->save();

        //    当下时间就是下预约的时间，马上通电
        //    因为crontab电源巡逻是5， 15， 25， 为了避免用户是在预约前5分钟下单，就没有电了
        if (empty($config['yunding_domain'])
            || empty($config['yunding_client_id'])
            || empty($config['yunding_client_secret'])
            || empty($roomInfo->yunding_homeid)
            || empty($roomInfo->yunding_elemetor_uuid)) {

        } else {
            if (Ykxbon::now()->betweenIncluded($startTime->subMinute(6), $endTime)) {
                $yunding = new Yunding();
                $yunding->elemeterSwitchOn($roomInfo->yunding_homeid, $roomInfo->yunding_elemetor_uuid);
            }
        }

        $this->success($msg);
    }

    public function cancelReserve()
    {
        $user = $this->auth->getUser();
        if (null == $user) {
            $this->error('未登录', '', 401);
        }
        $userId = $user->id;

        $id = $this->request->get('id');
        $reserve = ZzyyReserve::get($id, ['room']);

        if (!$reserve) {
            $this->error('没有此预约');
        }

        $rentRefund = ZzyySetting::getRentRefund();

        if (0 == $rentRefund) {
            $this->error('对不起，当前设置为不可自主取消预约');
        }

        if (ZzyyReserve::STATUS_CANCELLED == $reserve->status) {
            $this->error('已经取消, 不需重复操作');
        }

        if (Ykxbon::parse($reserve->starttime)->subHour($rentRefund)->isBefore(Ykxbon::now())) {
            $this->error("对不起, 已经超过提前{$rentRefund}小时可取消预约的时间");
        }

        Db::startTrans();

        try {
            if (ZzyyReserve::PAY_WAY_BALANCE == $reserve->pay_way) { // 余额支付

                $userExtend = ZzyyUserExtend::where('user_id', $userId)->find();
                $afterValue = $userExtend->balance + $reserve->fee;

                ZzyyUserBalance::create([
                    'user_id' => $userId,
                    'type' => ZzyyUserBalance::TYPE_SYSTEM_REFUND, //系统返还
                    'value' => $reserve->fee,
                    'before_value' => $userExtend->balance,
                    'after_value' => $afterValue,
                    'createtime' => time(),
                    'updatetime' => time()
                ]);

                $userExtend->balance = $afterValue;
                $userExtend->save();

            } else if (ZzyyReserve::PAY_WAY_DIRECT == $reserve->pay_way) { // 微信支付

                $trans = ZzyyTransaction::get($reserve->transaction_id);

                $result = Weixin::getInstance()->refunds($trans->transaction_no, $trans->out_trade_no, $trans->fee, $trans->fee);

                if (isset($result['transaction_id'])) {
                    $trans->status = ZzyyTransaction::STATUS_REFUND; // 标识为退款
                    $trans->save();
                } else {
                    throw new \Exception('退款出现错误，请联系管理员');
                }
            }

            // 标记Reserve是取消了
            $reserve->status = ZzyyReserve::STATUS_CANCELLED;
            $reserve->save();

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }

        $this->success('当前预约取消成功');

    }

    public function getFullInfo()
    {
        $id = $this->request->get('id');

        $reserve = \addons\zzyy\module\Reserve::getReserveFullInfo($id);

        $this->success('ok', $reserve);

    }

    public function remove()
    {
        $id = $this->request->get('id');
        $result = ZzyyReserve::get($id)->delete();

        if ($result) {
            $this->success('ok');
        } else {
            $this->error('删除失败');
        }
    }

}
